<!DOCTYPE HTML>
<!--generated with sswg-->
<html lang="en">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<head>
    <title> ursina engine documentation</title>
    <link rel="stylesheet" href="sswg.css">
    <link rel="stylesheet" href="style.css">
    <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<div style="max-width:1200px; margin:auto;">
<div style="text-align:left;">
<br>
<a href="index.html"><img src="ursina_logo_wireframe.webp" style="width:50px; height:auto; margin-right:10px;"/></a> <a href=" installation.html" class="button">Download</a> <a href=" documentation.html" class="button">Documentation</a> <a href=" api_reference_v8_2_0/index.html" class="button">API Reference</a> <a href=" samples.html" class="button">Samples</a> <a href=" asset_store.html" class="button">Asset Store</a> <a href=" donate.html" class="button">Donate</a><br>
<h1 id="FPS">
FPS
</h1><a href="https://github.com/pokepetter/ursina/blob/master/samples/fps.py">https://github.com/pokepetter/ursina/blob/master/samples/fps.py</a><br>
<br>
<img src="icons/fps.jpg"></img> <br>
<code_block id="code_block_0"><button class="copy_code_button" onclick="copy_to_clipboard(code_block_0)">copy</button><purple>from</purple> ursina <purple>import</purple> *
<purple>from</purple> ursina.prefabs.first_person_controller <purple>import</purple> FirstPersonController
<purple>from</purple> ursina.shaders <purple>import</purple> lit_with_shadows_shader

app = Ursina()

random.seed(<yellow>0</yellow>)
<olive>Entity</olive>.default_shader = lit_with_shadows_shader

ground = <olive>Entity</olive>(<olive>model</olive>=<green>'plane'</green>, <olive>collider</olive>=<green>'box'</green>, <olive>scale</olive>=<yellow>6</yellow><yellow>4</yellow>, <olive>texture</olive>=<green>'grass'</green>, <olive>texture_scale</olive>=(<yellow>4</yellow>,<yellow>4</yellow>))

editor_camera = EditorCamera(<olive>enabled</olive>=False, ignore_paused=True)
player = FirstPersonController(<olive>model</olive>=<green>'cube'</green>, <olive>z</olive>=-<yellow>1</yellow><yellow>0</yellow>, <olive>color</olive>=color.orange, origin_<olive>y</olive>=-.<yellow>5</yellow>, speed=<yellow>8</yellow>, <olive>collider</olive>=<green>'box'</green>)
player.collider = BoxCollider(player, Vec3(<yellow>0</yellow>,<yellow>1</yellow>,<yellow>0</yellow>), Vec3(<yellow>1</yellow>,<yellow>2</yellow>,<yellow>1</yellow>))

gun = <olive>Entity</olive>(<olive>model</olive>=<green>'cube'</green>, <olive>parent</olive>=camera, <olive>position</olive>=(.<yellow>5</yellow>,-.<yellow>2</yellow><yellow>5</yellow>,.<yellow>2</yellow><yellow>5</yellow>), <olive>scale</olive>=(.<yellow>3</yellow>,.<yellow>2</yellow>,<yellow>1</yellow>), origin_<olive>z</olive>=-.<yellow>5</yellow>, <olive>color</olive>=color.red, on_cooldown=False)
gun.muzzle_flash = <olive>Entity</olive>(<olive>parent</olive>=gun, <olive>z</olive>=<yellow>1</yellow>, world_<olive>scale</olive>=.<yellow>5</yellow>, <olive>model</olive>=<green>'quad'</green>, <olive>color</olive>=color.yellow, <olive>enabled</olive>=False)

shootables_parent = <olive>Entity</olive>()
mouse.traverse_target = shootables_parent


<purple>for</purple> i in <blue>range</blue>(<yellow>1</yellow><yellow>6</yellow>):
&nbsp;&nbsp;&nbsp;&nbsp;<olive>Entity</olive>(<olive>model</olive>=<green>'cube'</green>, origin_<olive>y</olive>=-.<yellow>5</yellow>, <olive>scale</olive>=<yellow>2</yellow>, <olive>texture</olive>=<green>'brick'</green>, <olive>texture_scale</olive>=(<yellow>1</yellow>,<yellow>2</yellow>),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x=random.uniform(-<yellow>8</yellow>,<yellow>8</yellow>),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<olive>z</olive>=random.uniform(-<yellow>8</yellow>,<yellow>8</yellow>) + <yellow>8</yellow>,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<olive>collider</olive>=<green>'box'</green>,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scale_y = random.uniform(<yellow>2</yellow>,<yellow>3</yellow>),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<olive>color</olive>=color.hsv(<yellow>0</yellow>, <yellow>0</yellow>, random.uniform(.<yellow>9</yellow>, <yellow>1</yellow>))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)

<purple>def</purple> update():
&nbsp;&nbsp;&nbsp;&nbsp;<purple>if</purple> held_keys[<green>'left mouse'</green>]:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shoot()

<purple>def</purple> shoot():
&nbsp;&nbsp;&nbsp;&nbsp;<purple>if</purple> <purple>not</purple> gun.on_cooldown:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<gray># <blue>print</blue>(<green>'shoot'</green>)</gray>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gun.on_cooldown = True
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gun.muzzle_flash.<olive>enabled</olive>=True
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<purple>from</purple> ursina.prefabs.ursfx <purple>import</purple> ursfx
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ursfx([(<yellow>0</yellow>.<yellow>0</yellow>, <yellow>0</yellow>.<yellow>0</yellow>), (<yellow>0</yellow>.<yellow>1</yellow>, <yellow>0</yellow>.<yellow>9</yellow>), (<yellow>0</yellow>.<yellow>1</yellow><yellow>5</yellow>, <yellow>0</yellow>.<yellow>7</yellow><yellow>5</yellow>), (<yellow>0</yellow>.<yellow>3</yellow>, <yellow>0</yellow>.<yellow>1</yellow><yellow>4</yellow>), (<yellow>0</yellow>.<yellow>6</yellow>, <yellow>0</yellow>.<yellow>0</yellow>)], volume=<yellow>0</yellow>.<yellow>5</yellow>, wave=<green>'noise'</green>, pitch=random.uniform(-<yellow>1</yellow><yellow>3</yellow>,-<yellow>1</yellow><yellow>2</yellow>), pitch_change=-<yellow>1</yellow><yellow>2</yellow>, speed=<yellow>3</yellow>.<yellow>0</yellow>)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;invoke(gun.muzzle_flash.disable, dela<olive>y</olive>=.<yellow>0</yellow><yellow>5</yellow>)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;invoke(setattr, gun, <green>'on_cooldown'</green>, False, dela<olive>y</olive>=.<yellow>1</yellow><yellow>5</yellow>)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<purple>if</purple> mouse.hovered_entity and <blue>hasattr</blue>(mouse.hovered_entity, <green>'hp'</green>):
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mouse.hovered_entity.hp -= <yellow>1</yellow><yellow>0</yellow>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mouse.hovered_entity.blink(color.red)


<purple>from</purple> ursina.prefabs.health_bar <purple>import</purple> HealthBar

class Enemy(<olive>Entity</olive>):
&nbsp;&nbsp;&nbsp;&nbsp;<purple>def</purple> __init__(self, **kwargs):
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super().__init__(<olive>parent</olive>=shootables_parent, <olive>model</olive>=<green>'cube'</green>, scale_<olive>y</olive>=<yellow>2</yellow>, origin_<olive>y</olive>=-.<yellow>5</yellow>, <olive>color</olive>=color.light_gray, <olive>collider</olive>=<green>'box'</green>, **kwargs)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.health_bar = <olive>Entity</olive>(<olive>parent</olive>=self, <olive>y</olive>=<yellow>1</yellow>.<yellow>2</yellow>, <olive>model</olive>=<green>'cube'</green>, <olive>color</olive>=color.red, world_<olive>scale</olive>=(<yellow>1</yellow>.<yellow>5</yellow>,.<yellow>1</yellow>,.<yellow>1</yellow>))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.max_hp = <yellow>1</yellow><yellow>0</yellow><yellow>0</yellow>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.hp = self.max_hp

&nbsp;&nbsp;&nbsp;&nbsp;<purple>def</purple> update(self):
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dist = distance_xz(player.position, self.position)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<purple>if</purple> dist &gt; <yellow>4</yellow><yellow>0</yellow>:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.health_bar.alpha = max(<yellow>0</yellow>, self.health_bar.alpha - time.dt)


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.look_at_<yellow>2</yellow>d(player.position, <green>'y'</green>)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hit_info = raycast(self.world_position + Vec3(<yellow>0</yellow>,<yellow>1</yellow>,<yellow>0</yellow>), self.forward, <yellow>3</yellow><yellow>0</yellow>, <olive>ignore</olive>=(self,))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<gray># <blue>print</blue>(hit_info.entity)</gray>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<purple>if</purple> hit_info.entity == player:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<purple>if</purple> dist &gt; <yellow>2</yellow>:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.position += self.forward * time.dt * <yellow>5</yellow>

&nbsp;&nbsp;&nbsp;&nbsp;@property
&nbsp;&nbsp;&nbsp;&nbsp;<purple>def</purple> hp(self):
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return self._hp

&nbsp;&nbsp;&nbsp;&nbsp;@hp.setter
&nbsp;&nbsp;&nbsp;&nbsp;<purple>def</purple> hp(self, value):
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self._hp = value
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<purple>if</purple> value &lt;= <yellow>0</yellow>:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;destroy(self)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.health_bar.world_scale_x = self.hp / self.max_hp * <yellow>1</yellow>.<yellow>5</yellow>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.health_bar.alpha = <yellow>1</yellow>

<gray># Enemy()</gray>
enemies = [Enemy(x=x*<yellow>4</yellow>) <purple>for</purple> x in <blue>range</blue>(<yellow>4</yellow>)]


<purple>def</purple> pause_input(key):
&nbsp;&nbsp;&nbsp;&nbsp;<purple>if</purple> key == <green>'tab'</green>:&nbsp;&nbsp;&nbsp;&nbsp;<gray># press tab to toggle edit/play mode</gray>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;editor_camera.enabled = <purple>not</purple> editor_camera.enabled

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;player.visible_self = editor_camera.enabled
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;player.cursor.enabled = <purple>not</purple> editor_camera.enabled
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gun.enabled = <purple>not</purple> editor_camera.enabled
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mouse.locked = <purple>not</purple> editor_camera.enabled
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;editor_camera.position = player.position

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;application.paused = editor_camera.enabled

pause_handler = <olive>Entity</olive>(ignore_paused=True, input=pause_input)


sun = DirectionalLight()
sun.look_at(Vec3(<yellow>1</yellow>,-<yellow>1</yellow>,-<yellow>1</yellow>))
Sky()

app.run()

</code_block>
<script>
function copy_to_clipboard(containerid) {
    var range = document.createRange()
    range.selectNode(containerid)
    window.getSelection().removeAllRanges()
    window.getSelection().addRange(range)
    document.execCommand("copy")
    window.getSelection().removeAllRanges()
}
</script>
<br>
<br>
</body>
</html>